using IQIGame.Onigao.Framework;
using System.IO;

namespace IQIGame.Onigao.Game
{
    public class NetworkChannelHelper : Singleton<NetworkChannelHelper>, INetworkChannelHelper
    {
        private NetworkChannelHelper()
        {

        }

        public int PacketHeaderLength
        {
            get
            {
                return BasePacket.HEAD_LENGTH;
            }
        }

        public BasePacket DeserializePacket(INetworkChannel networkChannel, PacketHeader packetHeader, Stream source, out object customErrorData)
        {
            ReceivePackage packet = ConcurrentClassPool<ReceivePackage>.Get();
            packet.InitWithoutHeadLength((source as MemoryStream).GetBuffer(), 0, packetHeader.PacketLength);
            packet.Header.Length = packetHeader.PacketLength + PacketHeaderLength - packet.Header.HeaderSize;
            packet.Active = true;
            customErrorData = null;
            return packet;
        }

        public PacketHeader DeserializePacketHeader(INetworkChannel networkChannel, Stream source, out object customErrorData)
        {
            PacketHeader header = ConcurrentClassPool<PacketHeader>.Get();
            header.PacketLength = ReadInt((source as MemoryStream).GetBuffer()) - PacketHeaderLength;
            customErrorData = null;
            return header;
        }

        private static int ReadInt(byte[] bytes)
        {
            int value = 0;
            for (int i = 0; i < 4; ++i)
            {
                value |= ((bytes[i] & 0xff) << ((i) * 8));
            }
            return value;
        }

        public void Initialize(INetworkChannel networkChannel)
        {

        }

        public bool SendHeartBeat(INetworkChannel networkChannel)
        {
            NetManager.Instance.SendHeartBeat(networkChannel);
            return true;
        }

        public bool Serialize<T>(INetworkChannel networkChannel, T packet, Stream destination) where T : BasePacket
        {
            SendPackage customPacket = packet as SendPackage;
            customPacket.FinishWrite();
            destination.Write(customPacket.OutputStream.Buf, 0, customPacket.OutputStream.Size);
            return true;
        }

        public void Shutdown(INetworkChannel networkChannel)
        {

        }
    }
}
